<template>
  <transition name="v-notification-fade" @after-leave="handleAfterLeave">
    <div
      :class="['v-notification', 'flex', showClose ? 'is-closable' : '',horizontalClass]"
      v-show="visible"
      role="alert"
      :style="positionStyle"
      @mouseenter="clearTimer"
      @mouseleave="startTimer"
    >
      <slot>
        <div v-if="!dangerouslyUseHTMLString" class="v-notification__content">
          <p class="v-notification_tit">{{ title }}</p>
          <p class="v-notification_message">{{ message }}</p>
        </div>
        <p v-else v-html="message" class="v-notification__content"></p>
      </slot>
      <i
        v-if="showClose"
        class="v-notification__icon v-icon-close"
        @click="close"
      ></i>
    </div>
  </transition>
</template>
<script>
export default {
  name: "message",
  data() {
    return {
      visible: false,
      message: "",
      title:'',
      duration: 3000,
      type: "info",
      onClose: null,
      showClose: false,
      closed: false,
      position: "top-right",
      verticalOffset: 20,
      timer: null,
      dangerouslyUseHTMLString: false,
      center: false,
    };
  },
  computed: {
    horizontalClass() {
      return this.position.indexOf("right") > -1 ? "right" : "left";
    },

    verticalProperty() {
      return /^top-/.test(this.position) ? "top" : "bottom";
    },

    positionStyle() {
        return {
          [this.verticalProperty]: `${ this.verticalOffset }px`
        };
    }
  },

  watch: {
    closed(newVal) {
      if (newVal) {
        this.visible = false;
      }
    },
  },

  methods: {
    handleAfterLeave() {
      this.$destroy(true);
      this.$el.parentNode.removeChild(this.$el);
    },

    close() {
      this.closed = true;
      if (typeof this.onClose === "function") {
        this.onClose(this);
      }
    },

    clearTimer() {
      clearTimeout(this.timer);
    },

    startTimer() {
      if (this.duration > 0) {
        this.timer = setTimeout(() => {
          if (!this.closed) {
            this.close();
          }
        }, this.duration);
      }
    },
    keydown(e) {
      if (e.keyCode === 27) {
        // esc关闭消息
        if (!this.closed) {
          this.close();
        }
      }
    },
  },
  mounted() {
    this.startTimer();
    document.addEventListener("keydown", this.keydown);
  },
  beforeDestroy() {
    document.removeEventListener("keydown", this.keydown);
  },
};
</script>
<style lang="less" scoped>
.v-notification {
  min-width: 320px;
  box-sizing: border-box;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  position: fixed;
  background-color: #fff;
  overflow: hidden;
  padding: 15px;
  z-index: 1000;
  box-shadow: 0 2px 12px 0 #f5f5f5;
  transition: opacity 0.3s, transform 0.3s, left 0.3s, right 0.3s, top 0.4s,
    bottom 0.3s;
  &.right{
    right:20px;
  }
  &.left{
    left:20px;
  }
  &.is-closable {
    .v-notification__content {
      margin-right: 25px;
    }
  }
  .v-notification__icon {
    display: inline-block;
    width: 23px;
    height: 23px;
    &.v-icon-close {
      position: absolute;
      top: 15px;
      right: 15px;
      cursor: pointer;
      &::before,
      &::after {
        position: absolute;
        top: 50%;
        left: 50%;
        content: "";
        display: block;
        width: 70%;
        height: 1px;
        background: #666;
      }
      &::before {
        transform: translate(-50%, -50%) rotate(45deg);
      }
      &::after {
        transform: translate(-50%, -50%) rotate(-45deg);
      }
    }
  }
  .v-notification__content {
    max-width: 500px;
    margin-left: 10px;
    flex: 1;
    word-break: break-all;
    .v-notification_tit {
      font-size: 16px;
      font-weight: bold;
    }
  }
}
// .v-notification-fade-enter,
// .v-notification-fade-leave-active {
//   opacity: 0;
//   transform: translateX(100%);
// }
.v-notification-fade-enter,.v-notification-fade-leave-active {
  opacity: 0;
  &.right {
    right: 0;
    transform: translateX(100%);
  }

  &.left {
    left: 0;
    transform: translateX(-100%);
  }
}

.v-notification-fade-leave-active {
  opacity: 0;
}
</style>
